import React, { useEffect } from "react";

import * as d3 from "d3";
import { VbpStatsByCadnI } from "../../../types";

interface PropsI {
  data: VbpStatsByCadnI[];
}

const GroupBarChartByCadnDept: React.FC<PropsI> = (props) => {
  const { data } = props;
  const refChart = React.useRef(null);

  useEffect(() => {
    if (refChart && refChart.current && data && data.length > 0) {
      const node = refChart.current;

      console.log(data);
      // 先按科室分组
      const dataBydept = d3.groups(data, (d) => d.deptYbName);
      console.log(dataBydept);

      // 将分组后的数据使用d3.rollup()汇总数据
      const aggregatedData = dataBydept.map((item) => {
        const subset = d3.rollup(
          item[1],
          (
            group // 对应每个分组的数据
          ) =>
            d3.sum(group, (d) => {
              return d.percent;
            }),
          (d) => d.cadn, // cadn
          (d) => d.vbpClass // vbpClass
        );
        const sortedSubset = d3.sort(subset, (a: any, b: any) => {
          if (a[1].get("中选") >= b[1].get("中选")) {
            return -1;
          } else {
            return 1;
          }
        });
        return [item[0], sortedSubset];
      });

      console.log(aggregatedData);

      const vbpClasses = new Set(data.map((d) => d.vbpClass));
      //   console.log(vbpClasses);
      //   console.log(vbpClasses.size);
      // 设定svg元素所占面积
      var rectStep = 45;
      const width = 1280;
      const height = (rectStep + 10) * data.length;
      // 设定四周边距
      const margin = { top: 50, right: 200, bottom: 30, left: 500 };

      d3.select(node).selectAll("svg").remove();
      var svg = d3
        .select(node)
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .attr("viewBox", [0, 0, width, height]) // 后续rect等图是相对viewBox计算的，viewBox可随svg绽放
        .attr("style", "max-width: 100%; height: auto;");

      const xScale = d3
        .scaleLinear()
        .domain([
          0,
          d3.max(data, (d: any) => {
            return d.percent;
          }),
        ])
        .range([0, width - margin.left - margin.right]);

      const deptSet = dataBydept.map((item) => item[0]);
      // 不同科室Y轴上分开展示
      const yDeptScale = d3
        .scaleBand()
        .domain(new Set(deptSet) as any)
        .rangeRound([0, height - margin.top - margin.bottom])
        .paddingInner(0.8);
      // console.log(yDeptScale("介入血管外科"));
      // console.log(yDeptScale("胸外科"));

      const deptColorScale = d3
        .scaleOrdinal()
        .domain(deptSet as any)
        .range(d3.schemeSpectral[11]);
      // console.log(deptColorScale("皮肤科"));

      // 不同集采类型分开
      const yVbpScale = d3
        .scaleBand()
        .domain(vbpClasses as any)
        .rangeRound([0, yDeptScale.bandwidth()])
        .padding(0.3);

      const colorScale = d3
        .scaleOrdinal()
        .domain(vbpClasses)
        // .range(d3.schemeSpectral[11]);
        .range(["green", "orange", "#335533", "blue"]);
      console.log(colorScale("中选"));

      // 添加 x 轴
      svg
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`)
        .call(d3.axisTop(xScale).tickSize(1));

      // 添加 y 轴
      svg
        .append("g")
        .attr("class", "yAxis")
        .attr("transform", `translate(${margin.left},${margin.top})`)
        .call(d3.axisLeft(yDeptScale).tickSize(0))
        .selectAll(".domain")
        .remove();
      // 去掉自动加的标签，后面手动加
      svg.selectAll(".yAxis").selectAll("text").remove();

      // 添加坐标轴标签
      svg
        .append("text")
        .attr("class", "x-label")
        .attr("text-anchor", "end")
        .attr("x", margin.left + (width - margin.left - margin.right) / 2) // 横坐标标签居中
        .attr("y", 20) // 位于 x 轴下方
        .text("比例");

      svg
        .append("text")
        .attr("class", "y-label")
        .attr("text-anchor", "middle")
        .attr("transform", "rotate(-90)") // 旋转 90 度；旋转后x, y属性也受影响
        .attr("x", -(margin.top + (height - margin.top - margin.bottom) / 2)) // 横坐标标签居中
        .attr("y", 30) // 向上偏移
        .text("科室——药品");

      // 每个科的药品可能不一样，所以所用纵向比例尺也不一样，需要给每个科画不同的比例尺
      const yCadnScales: any = new Map();
      aggregatedData.forEach(([key, value]: any) => {
        console.log(key, value);
        const cadnSet = new Set(value.map((item: any) => item[0]));
        console.log(cadnSet);
        const tmp = d3
          .scaleBand()
          .domain(cadnSet as any)
          .rangeRound([0, 300])
          .paddingInner(0.1);
        yCadnScales.set(key, tmp);
      });
      console.log(yCadnScales);

      // 画柱状图
      svg
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`) // 相对svg元素
        .selectAll()
        .data(aggregatedData)
        .join("g")
        .attr("transform", (D: any) => `translate(0, ${yDeptScale(D[0])})`) // 不同科室画不同位置
        // .attr("style", `background: ${(D: any) => deptColorScale(D[0])})`) // 不同科室画不同位置
        .selectAll()
        .data((D: any) => {
          console.log(D);
          return D[1].map((item: any) => {
            return {
              data: item,
              scale: yCadnScales.get(D[0]),
            };
          });
        })
        .join("g") // 每组通用名
        .attr("transform", (item: any) => {
          // console.log(item);
          // console.log(item.scale);
          // console.log(item.data[0]);
          // console.log(item.data[0]);
          // console.log(item.scale(item.data[0]));
          return `translate(0, ${item.scale(item.data[0])})`; // 不同通用名画不同位置
        })
        .selectAll()
        .data((d: any) => {
          // console.log(d);
          // console.log(d.data);
          return d.data[1];
        })
        .join("rect")
        .attr("x", 0)
        .attr("y", (d: any) => {
          // console.log(yScale.bandwidth());
          console.log(yVbpScale(d[0]));
          return yVbpScale(d[0]) || 0;
        })
        .attr("width", (d: any) => xScale(d[1]))
        .attr("height", (d: any) => yVbpScale.bandwidth())
        .attr("fill", (d: any) => colorScale(d[0]) as any);

      // 添加科室名称标签;
      svg
        .append("g") // 添加一大组存全部标签
        .attr("transform", `translate(${margin.left},${margin.top})`) // 相对svg元素
        .selectAll(".deptLabel") // 选择全部科室类标签，当前不存在，通过data生成
        .data(aggregatedData)
        .join("g")
        .attr("class", "deptLabel")
        // .attr("transform", `translate(,${margin.top})`) // 相对svg元素
        .append("text")
        .attr("font-weight", "bold")
        .attr("font-size", 16)
        .attr("x", -420)
        .attr("y", (D: any) => {
          // console.log(D);
          // console.log(yDeptScale.bandwidth());
          // return yDeptScale(D[0])! + yDeptScale.bandwidth();
          return yDeptScale(D[0])!;
        })
        .attr("dy", "0.35em")
        .text((D: any) => D[0]); // 画完科室分组标签

      // 添加药品通用名标签
      svg
        .append("g") // 选择全部科室类标签，当前不存在，通过data生成
        .attr("transform", `translate(${margin.left},${margin.top})`) // 相对svg元素
        .selectAll(".wrapper")
        .data(
          aggregatedData.map((D: any) => {
            console.log(D);
            return D[1].map((item: any) => {
              return {
                data: item,
                scale: yCadnScales.get(D[0]),
                dept: D[0],
              };
            });
          })
        )
        .join("g") // 每组通用名
        .attr("class", "wrapper")
        .attr("transform", (D: any) => {
          console.log(D);
          const { data, scale, dept } = D[0];
          // console.log(scale.bandwidth());
          // return `translate(0, ${scale.bandwidth() * data.length})`;
          return `translate(0, ${yDeptScale(dept)})`;
        }) // 不同科室画不同位置
        .selectAll(".cadnLabel")
        .data((d: any) => {
          console.log(d);
          return d;
        })
        .join("g")
        .attr("class", "cadnLabel")
        .append("text") // 每组通用名
        .attr("x", -300)
        .attr("y", (D: any) => {
          // console.log(D);
          const { data, scale } = D;
          // console.log(scale.bandwidth());
          return scale(data[0])! + scale.bandwidth();
        })
        .attr("dy", "0.35em")
        .text((D: any) => {
          // console.log(D.data[0]);
          return D.data[0];
        }) // 画完科室分组标签
        .append("g")
        .selectAll(".label")
        .data((d: any) => {
          // console.log(d.data);
          return d.data[1];
        })
        .join("text"); // text标签下无法再加text，下级text只能重新画;

      // 添加完成比例值标签
      svg
        .append("g") // 选择全部科室类标签，当前不存在，通过data生成
        .attr("transform", `translate(${margin.left},${margin.top})`) // 相对svg元素
        .selectAll(".wrapper")
        .data(
          aggregatedData.map((D: any) => {
            console.log(D);
            return D[1].map((item: any) => {
              return {
                data: item,
                scale: yCadnScales.get(D[0]),
                dept: D[0],
              };
            });
          })
        )
        .join("g") // 每组通用名
        .attr("class", "wrapper")
        .attr("transform", (D: any) => {
          console.log(D);
          const { data, scale, dept } = D[0];
          // console.log(scale.bandwidth());
          // return `translate(0, ${scale.bandwidth() * data.length})`;
          return `translate(0, ${yDeptScale(dept)})`;
        }) // 不同科室画不同位置
        .selectAll(".cadnLabel")
        .data((d: any) => {
          console.log(d);
          return d;
        })
        .join("g")
        .attr("class", "cadnLabel")
        .attr("transform", (D: any) => {
          console.log(D);
          const { data, scale, dept } = D;
          console.log(scale(data[0]));
          // return `translate(0, ${scale(data[0]) + scale.bandwidth()})`;
          return `translate(0, ${scale(data[0]) + scale.bandwidth() / 2})`;
        }) // 不同科室画不同位置
        .selectAll(".label")
        .data((d: any) => {
          console.log(d);
          console.log(d.data);
          return d.data[1];
        })
        .join("text") //
        .attr("class", ".label")
        .attr("x", (d: any) => {
          console.log(d);
          return xScale(d[1]) + 6;
        })
        .attr("y", (d: any) => {
          console.log(d);
          return yVbpScale(d[0]) || 0;
        })
        .text((d: any) => {
          return (d[1] * 100).toFixed(2) + "%";
        });

      //   // 添加图例
      //   const legend = svg
      //     .selectAll(".legend")
      //     .data(colorScale.domain())
      //     .join("g")
      //     .attr("class", "legend")
      //     .attr("transform", (d, i) => `translate(0,${i * 20 + 20})`);

      //   legend
      //     .append("rect")
      //     .attr("x", 18)
      //     .attr("width", 18)
      //     .attr("height", 18)
      //     .style("fill", colorScale as any);

      //   legend
      //     .append("text")
      //     .attr("x", 76)
      //     .attr("y", 9)
      //     .attr("dy", ".35em")
      //     .style("text-anchor", "end")
      //     .text((d) => d);
    }

    // 清除副作用;
    return () => {
      d3.select(refChart.current).selectAll("*").remove();
    };
  }, [data]);

  return (
    <div>
      <div ref={refChart}></div>
    </div>
  );
};

export default GroupBarChartByCadnDept;
